package com.yipei.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yipei.business.domain.MlDailySettlementInfo;
import com.yipei.business.domain.MlPositionShare;
import com.yipei.business.domain.MlTodayProfit;
import com.yipei.business.domain.MlTradeEntrustOrder;
import com.yipei.business.mapper.MlPositionShareMapper;
import com.yipei.business.service.*;
import com.yipei.business.vo.BuySellVo;
import com.yipei.business.vo.OptionalSymbolVo;
import com.yipei.business.vo.PositionShareVo;
import com.yipei.common.core.domain.entity.MlTradeAccount;
import com.yipei.common.utils.DateUtils;
import com.yipei.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 持仓股票Service业务层处理
 *
 * @author yipei
 * @date 2024-12-21
 */
@Service
public class MlPositionShareServiceImpl extends ServiceImpl<MlPositionShareMapper, MlPositionShare> implements IMlPositionShareService {
    @Autowired
    private MlPositionShareMapper mlPositionShareMapper;
    @Autowired
    private IMlOptionalSymbolService iMlOptionalSymbolService;
    @Autowired
    private IMlDailySettlementInfoService iMlDailySettlementInfoService;
    @Autowired
    private IMlTodayProfitService iMlTodayProfitService;

    @Autowired
    private IMlTradeAccountService iMlTradeAccountService;

    /**
     * 查询持仓股票
     *
     * @param id 持仓股票主键
     * @return 持仓股票
     */
    @Override
    public MlPositionShare selectMlPositionShareById(Long id) {
        return mlPositionShareMapper.selectMlPositionShareById(id);
    }

    /**
     * 查询持仓股票列表
     *
     * @param mlPositionShare 持仓股票
     * @return 持仓股票
     */
    @Override
    public List<MlPositionShare> selectMlPositionShareList(MlPositionShare mlPositionShare) {
        return mlPositionShareMapper.selectMlPositionShareList(mlPositionShare);
    }

    /**
     * 新增持仓股票
     *
     * @param mlPositionShare 持仓股票
     * @return 结果
     */
    @Override
    public int insertMlPositionShare(MlPositionShare mlPositionShare) {
        mlPositionShare.setCreateTime(DateUtils.getNowDate());
        return mlPositionShareMapper.insertMlPositionShare(mlPositionShare);
    }

    /**
     * 修改持仓股票
     *
     * @param mlPositionShare 持仓股票
     * @return 结果
     */
    @Override
    public int updateMlPositionShare(MlPositionShare mlPositionShare) {
        mlPositionShare.setUpdateTime(DateUtils.getNowDate());
        return mlPositionShareMapper.updateMlPositionShare(mlPositionShare);
    }

    /**
     * 批量删除持仓股票
     *
     * @param ids 需要删除的持仓股票主键
     * @return 结果
     */
    @Override
    public int deleteMlPositionShareByIds(Long[] ids) {
        return mlPositionShareMapper.deleteMlPositionShareByIds(ids);
    }

    /**
     * 删除持仓股票信息
     *
     * @param id 持仓股票主键
     * @return 结果
     */
    @Override
    public int deleteMlPositionShareById(Long id) {
        return mlPositionShareMapper.deleteMlPositionShareById(id);
    }

    @Override
    public void createpositionShareData(PositionShareVo positionShareVo, List<MlPositionShare> mlPositionShares, MlTradeAccount mlTradeAccount) throws IOException {
        positionShareVo.setCash(mlTradeAccount.getCash().setScale(2, RoundingMode.DOWN));
        positionShareVo.setTd_acc(mlTradeAccount.getTdAcc());
        positionShareVo.setCost(mlTradeAccount.getCost());
        positionShareVo.setLock(mlTradeAccount.getDjCash());
        BigDecimal z_sz = BigDecimal.ZERO;
        BigDecimal fd_yk = BigDecimal.ZERO;
        BigDecimal dr_yk = BigDecimal.ZERO;
        BigDecimal z_zc = BigDecimal.ZERO;
        for (MlPositionShare positionShare : mlPositionShares) {
            OptionalSymbolVo optionalSymbolVo = new OptionalSymbolVo();
            List<OptionalSymbolVo> optionalList = iMlOptionalSymbolService.createOptionalList(positionShare.getSymbol(), optionalSymbolVo);
            if (!CollectionUtils.isEmpty(optionalList)) {
                positionShare.setPrice(optionalList.get(0).getPrice());
                positionShare.setSec_name(optionalList.get(0).getSec_name());
                positionShare.setF12(optionalList.get(0).getF12());
                positionShare.setF14(optionalList.get(0).getF14());
                positionShare.setRatio(optionalList.get(0).getRatio());
            }
            positionShare.setCcDh(positionShare.getCcDh());
            positionShare.setYh_yl(positionShare.getYhYl());
            positionShare.setKy_cw(positionShare.getKyCw());
            positionShare.setCost(positionShare.getCbJj());
            //            positionShare.setAmount((positionShare.getKyCw()==null? BigDecimal.ZERO :positionShare.getKyCw()).add(positionShare.getSdCw()==null?BigDecimal.ZERO:positionShare.getSdCw()).add(positionShare.getJrCw()==null?BigDecimal.ZERO:positionShare.getJrCw()));
            BigDecimal cwSum = positionShare.getKyCw() == null ? BigDecimal.ZERO : positionShare.getKyCw().add(positionShare.getSdCw() == null ? BigDecimal.ZERO : positionShare.getSdCw().add(positionShare.getJrCw() == null ? BigDecimal.ZERO : positionShare.getJrCw()));
            z_sz = z_sz.add(cwSum.multiply(new BigDecimal(positionShare.getPrice())));
            fd_yk = fd_yk.add(cwSum.multiply(new BigDecimal(positionShare.getPrice()).subtract(positionShare.getCbJj())).add(positionShare.getYhYl() == null ? BigDecimal.ZERO : positionShare.getYhYl()));
        }
//          dr_yk = round(trade.cash + trade.lock + ps.get('z_sz') - dsi.z_zc, 2)

        LambdaQueryWrapper<MlDailySettlementInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.and(i -> i.eq(MlDailySettlementInfo::getTdAcc, mlTradeAccount.getTdAcc())
        );
        List<MlDailySettlementInfo> mlDailySettlementInfos = iMlDailySettlementInfoService.list(lambdaQueryWrapper);
        if (CollectionUtils.isEmpty(mlDailySettlementInfos)) {
            z_zc = BigDecimal.ZERO;
        } else {
            z_zc = mlDailySettlementInfos.get(0).getZZc();
        }
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date();
        String now = formatter.format(date);
        MlTodayProfit one = iMlTodayProfitService.lambdaQuery().eq(MlTodayProfit::getTdAcc, mlTradeAccount.getTdAcc()).eq(MlTodayProfit::getTdDay, now).one();
        if (one != null) {
            dr_yk = one.getProfit();
        }
        positionShareVo.setZ_sz(z_sz);
        positionShareVo.setFd_yk(fd_yk);
        positionShareVo.setDr_yk(dr_yk);
        positionShareVo.setKq_zj(mlTradeAccount.getKqZj());
        //java中list将symbol字段相同的数据kyCw相加
//        mlPositionShares.stream().filter()
        // 分组求和
        // 按 symbol 分组
        Map<String, List<MlPositionShare>> grouped = mlPositionShares.stream()
                .collect(Collectors.groupingBy(MlPositionShare::getSymbol));
        // 合并 kyCw，其他字段取第一个
        List<MlPositionShare> resultList = grouped.values().stream()
                .map(list -> {
                    MlPositionShare first = list.get(0); // 取第一个作为基准
                    BigDecimal sumKyCw = list.stream()
                            .map(MlPositionShare::getKyCw)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    first.setKyCw(sumKyCw); // 设置累计值
                    BigDecimal sum = list.stream().filter(e -> {
                                LocalDate createDate = e.getCreateTime().toInstant()
                                        .atZone(ZoneId.systemDefault())
                                        .toLocalDate();
                                LocalDate today = LocalDate.now();
                                return createDate.isBefore(today);
                            })
                            .map(MlPositionShare::getKy_cw)
                            .reduce(BigDecimal.ZERO, BigDecimal::add);
                    first.setKyCw(sumKyCw);
                    first.setKy_cw(sum);
                    first.setAmount(sumKyCw);
                    return first;
                })
                .collect(Collectors.toList());

        positionShareVo.setP_list(resultList);
    }

    @Override
    public BuySellVo ceratePositionShare(String f12, BigDecimal price, String id) {
        BuySellVo buySellVo = new BuySellVo();
        MlTradeAccount mlTradeAccount = SecurityUtils.getLoginMember().getMlTradeAccount();
        MlTradeAccount one = iMlTradeAccountService.lambdaQuery().eq(MlTradeAccount::getTdAcc, mlTradeAccount.getTdAcc()).one();

        buySellVo.setTd_acc(one.getTdAcc());
        buySellVo.setSymbol(f12);
        LocalDate date = LocalDateTime.now().toLocalDate();
        LambdaQueryWrapper<MlPositionShare> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(MlPositionShare::getTdAcc, one.getTdAcc()).eq(MlPositionShare::getSymbol, f12).lt(MlPositionShare::getCreateTime, date);
        List<MlPositionShare> mlPositionShares = this.list(lambdaQueryWrapper);
        BigDecimal ky_cw = mlPositionShares.stream().map(MlPositionShare::getKyCw).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (ObjectUtils.isEmpty(mlPositionShares)) {
            buySellVo.setKy_cw(BigDecimal.ZERO);
        } else {
            buySellVo.setKy_cw(ky_cw);
        }
        // (trade.cash/sp.get('price')/100)*100
        buySellVo.setKm_cw(one.getCash().divide(price, 0, RoundingMode.FLOOR));
//        buySellVo.setId(mlPositionShares.getId());
        return buySellVo;
    }

    @Override
    public Map<String, List<MlPositionShare>> getPositionMapByTdAccAndSymbol(List<MlTradeEntrustOrder> orders) {
        if (orders == null || orders.isEmpty()) {
            return Collections.emptyMap();
        }
        // 提取所有tdAcc和symbol组合
        Set<String> tdAccSymbolSet = orders.stream()
                .map(o -> o.getTdAcc() + "_" + o.getSymbol())
                .collect(Collectors.toSet());

        // 拆分tdAcc和symbol，批量查询所有相关持仓
        Set<String> tdAccSet = orders.stream().map(MlTradeEntrustOrder::getTdAcc).collect(Collectors.toSet());
        Set<String> symbolSet = orders.stream().map(MlTradeEntrustOrder::getSymbol).collect(Collectors.toSet());

        List<MlPositionShare> allShares = this.list(
                new LambdaQueryWrapper<MlPositionShare>()
                        .in(MlPositionShare::getTdAcc, tdAccSet)
                        .in(MlPositionShare::getSymbol, symbolSet)
        );

        // 按 tdAcc + symbol 组合分组
        return allShares.stream().collect(Collectors.groupingBy(
                s -> s.getTdAcc() + "_" + s.getSymbol()
        ));
    }


}
